package com.haiyou.common.spring.listener;

import java.util.Collections;
import java.util.List;

import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.stereotype.Component;

import com.google.common.collect.Lists;
import com.haiyou.common.event.asyc.AsyncEventBuses;
import com.haiyou.common.spring.component.LifecycleableComponent;
import com.haiyou.common.spring.component.LifecycleableComponentFilter;
import com.haiyou.common.spring.event.SpringApplicationContextReadyEvent;
import com.haiyou.common.spring.util.SpringUtil;
import com.haiyou.common.util.system.PidUtils;

import lombok.extern.slf4j.Slf4j;

/**
 * @author xingyuan
 * @Description: spring 初始化完成
 * @date 2022年5月17日 下午8:53:18
 */
@Component
@Slf4j
public class SpringContextRefreshedListener implements ApplicationListener<ContextRefreshedEvent> {

    @Override
    public void onApplicationEvent(ContextRefreshedEvent event) {

        log.info(String.format("spring event ......%s......", event));

        LifecycleableComponentFilter filter = null;

        try {
            filter = SpringUtil.getBean(LifecycleableComponentFilter.class);
        } catch (Exception e) {
        }

        List<LifecycleableComponent> lifecycles = Lists
                .newArrayList(SpringUtil.getBeansOfType(LifecycleableComponent.class).values());

        Collections.sort(lifecycles);

        for (int i = 0; i < lifecycles.size(); i++) {
            log.debug(String.format("starting ......%s......", lifecycles.get(i)));
            //log.info("init class:{}",lifecycles.get(i).getClass().getSimpleName());

            //有些类不需要执行
            if (filter != null) {
                if (filter.match(lifecycles.get(i).getClass())) {
                    continue;
                }
            }

            lifecycles.get(i).start();
            log.debug(String.format("started ......%s......", lifecycles.get(i)));
        }

        AsyncEventBuses.getInstance().postEvent(new SpringApplicationContextReadyEvent());

        Runtime.getRuntime().addShutdownHook(new Thread(() -> {

            SpringRobot.getInstance().invokeRobotDestroy();

            String pid = PidUtils.getPid();
            log.info(String.format("Processor[%s] stopping!", pid));
            ((AbstractApplicationContext) event.getApplicationContext()).close();
            log.info(String.format("Processor[%s] stopped!", pid));
        }));

    }

}
